package com.prs.crm.service.project.impl;

import java.io.File;
import java.util.Collection;
import java.util.Date;

import org.courser.ui.PaginationSupport;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;

import com.prs.crm.context.Constrains;
import com.prs.crm.context.FileUtil;
import com.prs.crm.context.ToolKits;
import com.prs.crm.dao.project.ProjectDao;
import com.prs.crm.domain.Attachment;
import com.prs.crm.domain.flow.WorkFlowProcess;
import com.prs.crm.domain.flow.WorkFlowProcessNode;
import com.prs.crm.domain.hr.Person;
import com.prs.crm.domain.oa.Notice;
import com.prs.crm.domain.project.Project;
import com.prs.crm.domain.project.Task;
import com.prs.crm.exception.InValidException;
import com.prs.crm.service.hr.PersonService;
import com.prs.crm.service.impl.FlowServiceImpl;
import com.prs.crm.service.oa.NoticeService;
import com.prs.crm.service.project.ProjectService;
import com.prs.crm.service.project.TaskService;

public class ProjectServiceImpl  extends FlowServiceImpl<Project,ProjectDao> implements ProjectService{

	private PersonService personService;
	
	private TaskService  taskService;
	
	private NoticeService noticeService;
	
	@Autowired
	public void setPersonService(PersonService personService) {
		this.personService = personService;
	}

	public PersonService getPersonService() {
		return personService;
	}

	@Autowired
	public void setTaskService(TaskService taskService) {
		this.taskService = taskService;
	}

	public TaskService getTaskService() {
		return taskService;
	}
	
	

	public NoticeService getNoticeService() {
		return noticeService;
	}
	@Autowired
	public void setNoticeService(NoticeService noticeService) {
		this.noticeService = noticeService;
	}

	public void createProject(Project project,Task task,String joiner,File[] references,String[] fileNames)
	{
		if (project.getEndTime().compareTo(project.getStartTime())<0)
			throw new InValidException("项目结束时间不能早于开始时间");
		project.setStatus(Constrains.PROJECT_STATUS_PROCESS);
		project.addAllReference(FileUtil.getInstance().createAttach(references, fileNames));
		super.save(project);
		Collection<Person> joiners = this.getPersonService().findPersons(ToolKits.convertStringAryToIntAry(joiner.split(",")));
		task.addAllJoiner(joiners);
		
		taskService.createTask(task,project);
	}

	
	public PaginationSupport listCreateProject(PaginationSupport page,Person recorder)
	{
		DetachedCriteria criteria = this.createQuery(Project.class);
		criteria.add(Restrictions.eq("recorder", recorder))
				.add(Restrictions.eq("status", Constrains.PROJECT_STATUS_PROCESS));
		return super.listByPage(criteria, page);
	}
	
	public PaginationSupport listFrostProject(PaginationSupport page,Person creater)
	 {
		DetachedCriteria criteria = this.createQuery(Project.class);
		criteria.add(Restrictions.eq("recorder", creater))
				.add(Restrictions.eq("status", Constrains.PROJECT_STATUS_FROST));
		return super.listByPage(criteria, page);
	}

	
	public  PaginationSupport listAllProject(PaginationSupport page)
	{
		DetachedCriteria criteria = this.createQuery(Project.class);
		return super.listByPage(criteria, page); 
	}
	
	public  PaginationSupport listHistoryProject(PaginationSupport page,Person recorder)
	{

		DetachedCriteria criteria = this.createQuery(Project.class);
		criteria.add(Restrictions.eq("recorder", recorder))
				.add(Restrictions.eq("status", Constrains.PROJECT_STATUS_END));
		return super.listByPage(criteria, page);
	}
	

	
	/**
	 * 流程执行结束
	 */
	public void onProcessEnd(WorkFlowProcess process)
	{
		super.onProcessEnd(process);
		Project project = this.getProcessEntity(process);
		if (process.getResult()==Constrains.WORKFLOWPROCESS_RESULT_PASS)
		{
			project.setStatus(Constrains.PROJECT_STATUS_END);
		}
		else
		{
			/**
			 * 如果项目审核被打回，则项目下所有的任务状态都设置为未完成
			 */
			project.setStatus(Constrains.PROJECT_STATUS_PROCESS);
			this.getTaskService().updateProjectTaskStatus(project
						, Constrains.TASK_STATUS_PROCESS, Constrains.WORKFLOWENTITY_STATE_INVALID);
		}
		super.save(project);
	}
	
	@Override
	public boolean valideSubmit(Project project)
	{
//		Task task = this.getTaskService().findRootTask(project);
//		if (task.getStatus()==Constrains.TASK_STATUS_END)
//		{
			return true;
//		}
//		else
//		{
//			return false;
//		}
	}
	
	/**
	 * 发送项目审核通知
	 */
	@Override
	public void onNextStep(Project project,Collection<WorkFlowProcessNode> nextNodes )
	{
		if (nextNodes!=null)
		{
			for (WorkFlowProcessNode node : nextNodes)
			{
				if (node.getInstanceNode()!=null)
				{
					if (node.getInstanceNode().getHandler().getPrincipal()!=null)
					{
						Notice notice = new Notice();
						notice.setTitle("新的项目审核任务:"+project.getName());
						notice.setContent("您有新的项目审核任务:"+project.getName()+",请及时处理");
						this.getNoticeService().sendNotice(notice, node.getInstanceNode().getHandler().getPrincipal());
					}
					Collection<Person> executors = null;
					if (node.getInstanceNode().getHandler().getExecutors()!=null
								&& node.getInstanceNode().getHandler().getExecutors().size()>0)
					{
						executors = node.getInstanceNode().getHandler().getExecutors();
					}
					else if (node.getHandler().getDept()!=null
							&& node.getHandler().getRole()!=null)
					{
						executors = this.getPersonService().getDeptRolePersons(node.getHandler().getDept(), 
								node.getHandler().getRole());
					}
					if (executors!=null)
					{
						for (Person executor :executors)
						{
							Notice notice = new Notice();
							notice.setTitle("新的项目审核任务:"+project.getName());
							notice.setContent("您有新的项目审核任务:"+project.getName()+",请及时处理");
							this.getNoticeService().sendNotice(notice,executor);
						}
					}
				}
			}
		}
		
	}
	
	public 	void removeProjectReference(Project project,Attachment reference)
	{
		project.getReferences().remove(reference);
		super.save(project);
	}
	
	public void executeFrostProject(Project project)
	{
		if (project.getProcessed())
			throw new InValidException("该项目正在审核中,不能冻结");
		if (project.getLocked())
			throw new InValidException("该项目已被锁定,不能冻结");

		project.setStatus(Constrains.PROJECT_STATUS_FROST);
		super.save(project);
		this.getTaskService().executeFrostProjectTasks(project);
	}
	
	public void executeUnfreezeProject(Project project)
	{
		if (project.getStatus() == Constrains.PROJECT_STATUS_FROST)
		{
			project.setStatus(Constrains.PROJECT_STATUS_PROCESS);
			super.save(project);
			this.getTaskService().executeUnFreezeProjectTasks(project);
		}
	}
	
	public void executeVaryProject(Project project,File[] references,String[] fileNames)
	{
		project.addAllReference(FileUtil.getInstance().createAttach(references, fileNames));
		super.save(project);
	}

	@Override
	public Collection<?> getProjectReportDataSource(Integer state,
			Date datestart, Date dateend, Collection<Person> persons) {
		// TODO Auto-generated method stub
		return this.getDao().getProjectReportDataSource(state, datestart, dateend, persons);
	}

}
